package com.tomcat.mesos.master;

import org.apache.mesos.Protos;
import org.apache.mesos.Scheduler;
import org.apache.mesos.SchedulerDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * Mesos 调度器，获取资源并响应相关联执行器的资源请求。
 * @author Rayn on 2015/12/22 10:44
 * @email liuwei412552703@163.com
 */
public class MesosScheduler implements Scheduler
{
    private static final Logger LOG = LoggerFactory.getLogger(MesosScheduler.class);


    /**
     * 调度器向 Mesos master 注册
     *
     * @param driver
     * @param frameworkId   由Mesos提供的全局唯一 ID
     * @param masterInfo
     */
    @Override
    public void registered(SchedulerDriver driver, Protos.FrameworkID frameworkId, Protos.MasterInfo masterInfo)
    {
        LOG.info("向Master 注册，ID :" + frameworkId.getValue() + ", MasterInfo : [" + masterInfo.getHostname() + "]");





    }

    /**
     * 框架调度器向新选举的 master 重新注册后调用。
     * @param driver
     * @param masterInfo
     */
    @Override
    public void reregistered(SchedulerDriver driver, Protos.MasterInfo masterInfo)
    {
        LOG.info("向新选举的 Master 注册，MasterInfo : [" + masterInfo.getHostname() + "]");



    }

    /**
     * resourceOffers 在 master 向框架提供资源 offer 时调用。每一份资源 offer 包含从某个 slave 上获取的资源列表。
     * 调度器可以接受资源 offer 并利用 offerIds 来启动任务,也可以拒绝资源 offer.
     * @param driver
     * @param offers
     */
    @Override
    public void resourceOffers(SchedulerDriver driver, List<Protos.Offer> offers)
    {
        LOG.info("Scheduler 接受到 offer, size : " + offers.size());



    }

    /**
     * master 撤销发送给框架的资源 offer 时调用。
     * @param driver
     * @param offerId
     */
    @Override
    public void offerRescinded(SchedulerDriver driver, Protos.OfferID offerId)
    {
        LOG.info("Scheduler 撤销发送的 offer, offerId:" + offerId);


    }

    /**
     * mesos 向框架发送消息，任务状态发生变化，如任务结束或由于slave 丢失而导致任务丢失。
     *
     * 可以使用该方法来跟踪框架下工作的进度。
     *
     * @param driver
     * @param status
     */
    @Override
    public void statusUpdate(SchedulerDriver driver, Protos.TaskStatus status)
    {
        LOG.info("任务状态 :" + status.getTaskId().getValue() + ", state is :" + status.getState());

    }

    /**
     * 向调度器传递执行器发送的消息
     *
     * 调度器可以访问执行器和 slave 的ID，以及调度器所发送的数据。
     *
     * @param driver
     * @param executorId
     * @param slaveId
     * @param data
     */
    @Override
    public void frameworkMessage(SchedulerDriver driver, Protos.ExecutorID executorId, Protos.SlaveID slaveId, byte[] data)
    {

    }

    /**
     * 调度器和Master断开连接调用
     * @param driver
     */
    @Override
    public void disconnected(SchedulerDriver driver)
    {
        LOG.info("调度器与 master 断开。");


    }

    /**
     * 通知调度器无法和指定 ID的slave 进行通信。
     *
     * @param driver
     * @param slaveId
     */
    @Override
    public void slaveLost(SchedulerDriver driver, Protos.SlaveID slaveId)
    {
        LOG.info("调度器无法和 " + slaveId.getValue() + " 通信.");

    }

    /**
     * 通知调度器特定的执行器已经以指定的状态结束。
     * @param driver
     * @param executorId
     * @param slaveId
     * @param status
     */
    @Override
    public void executorLost(SchedulerDriver driver, Protos.ExecutorID executorId, Protos.SlaveID slaveId, int status)
    {
        LOG.info("调度器ID:" + executorId + ", 执行器ID:" + slaveId + "。。。。当前状态:" + status);


    }

    /**
     * 可恢复的错误产生或者调度器和驱动停止工作时被调用。
     *
     * <em>清理所有使用到的资源，如锁和其他资源。</em>
     *
     * @param driver
     * @param message
     */
    @Override
    public void error(SchedulerDriver driver, String message)
    {
        LOG.info("发送异常。异常信息：" + message);



    }
}
